package com.macro.mall.service.impl;


import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.macro.mall.common.exception.Asserts;
import com.macro.mall.common.utils.*;
import com.macro.mall.dao.OmsOrderDao;
import com.macro.mall.dao.OmsOrderOperateHistoryDao;
import com.macro.mall.dto.*;
import com.macro.mall.mapper.OmsOrderMapper;
import com.macro.mall.mapper.OmsOrderOperateHistoryMapper;
import com.macro.mall.mapper.UmsMemberMapper;
import com.macro.mall.model.OmsOrder;
import com.macro.mall.model.OmsOrderExample;
import com.macro.mall.model.OmsOrderOperateHistory;
import com.macro.mall.model.UmsMemberExample;
import com.macro.mall.service.OmsOrderService;
import com.macro.mall.vo.LogisticsVO;
import com.macro.mall.vo.OrderTrackingVO;
import net.sf.json.JSONObject;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单管理Service实现类
 * Created by macro on 2018/10/11.
 */
@Service
public class OmsOrderServiceImpl implements OmsOrderService {
    @Autowired
    private OmsOrderMapper orderMapper;
    @Autowired
    private OmsOrderDao orderDao;
    @Autowired
    private OmsOrderOperateHistoryDao orderOperateHistoryDao;
    @Autowired
    private OmsOrderOperateHistoryMapper orderOperateHistoryMapper;
    @Autowired
    private UmsMemberMapper memberMapper;
    @Autowired
    private Environment env;
    @Override
    public List<OmsOrder> list(OmsOrderQueryParam queryParam, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        return orderDao.getList(queryParam);
    }

    @Override
    public int delivery(List<OmsOrderDeliveryParam> deliveryParamList) {
        //批量发货
        int count = orderDao.delivery(deliveryParamList);
        //添加操作记录
        List<OmsOrderOperateHistory> operateHistoryList = deliveryParamList.stream()
                .map(omsOrderDeliveryParam -> {
                    OmsOrderOperateHistory history = new OmsOrderOperateHistory();
                    history.setOrderId(omsOrderDeliveryParam.getOrderId());
                    history.setCreateTime(new Date());
                    history.setOperateMan("后台管理员");
                    history.setOrderStatus(2);
                    history.setNote("完成发货");
                    return history;
                }).collect(Collectors.toList());
        orderOperateHistoryDao.insertList(operateHistoryList);
        return count;
    }

    @Override
    public int close(List<Long> ids, String note) {
        OmsOrder record = new OmsOrder();
        record.setStatus(4);
        OmsOrderExample example = new OmsOrderExample();
        example.createCriteria().andDeleteStatusEqualTo(0).andIdIn(ids);
        int count = orderMapper.updateByExampleSelective(record, example);
        List<OmsOrderOperateHistory> historyList = ids.stream().map(orderId -> {
            OmsOrderOperateHistory history = new OmsOrderOperateHistory();
            history.setOrderId(orderId);
            history.setCreateTime(new Date());
            history.setOperateMan("后台管理员");
            history.setOrderStatus(4);
            history.setNote("订单关闭:"+note);
            return history;
        }).collect(Collectors.toList());
        orderOperateHistoryDao.insertList(historyList);
        return count;
    }

    @Override
    public int delete(List<Long> ids) {
        OmsOrder record = new OmsOrder();
        record.setDeleteStatus(1);
        OmsOrderExample example = new OmsOrderExample();
        example.createCriteria().andDeleteStatusEqualTo(0).andIdIn(ids);
        return orderMapper.updateByExampleSelective(record, example);
    }

    @Override
    public OmsOrderDetail detail(Long id) {
        OmsOrderDetail detail = orderDao.getDetail(id);
        detail.setMember(memberMapper.selectByPrimaryKey(detail.getMemberId()));
        detail.getMember().setOpenId(null);
        return detail;
    }

    @Override
    public int updateReceiverInfo(OmsReceiverInfoParam receiverInfoParam) {
        OmsOrder order = new OmsOrder();
        order.setId(receiverInfoParam.getOrderId());
        order.setReceiverName(receiverInfoParam.getReceiverName());
        order.setReceiverPhone(receiverInfoParam.getReceiverPhone());
        order.setReceiverPostCode(receiverInfoParam.getReceiverPostCode());
        order.setReceiverDetailAddress(receiverInfoParam.getReceiverDetailAddress());
        order.setReceiverProvince(receiverInfoParam.getReceiverProvince());
        order.setReceiverCity(receiverInfoParam.getReceiverCity());
        order.setReceiverRegion(receiverInfoParam.getReceiverRegion());
        order.setModifyTime(new Date());
        int count = orderMapper.updateByPrimaryKeySelective(order);
        //插入操作记录
        OmsOrderOperateHistory history = new OmsOrderOperateHistory();
        history.setOrderId(receiverInfoParam.getOrderId());
        history.setCreateTime(new Date());
        history.setOperateMan("后台管理员");
        history.setOrderStatus(receiverInfoParam.getStatus());
        history.setNote("修改收货人信息");
        orderOperateHistoryMapper.insert(history);
        return count;
    }

    @Override
    public int updateMoneyInfo(OmsMoneyInfoParam moneyInfoParam) {
        OmsOrder order = new OmsOrder();
        order.setId(moneyInfoParam.getOrderId());
        order.setFreightAmount(moneyInfoParam.getFreightAmount());
        order.setDiscountAmount(moneyInfoParam.getDiscountAmount());
        order.setModifyTime(new Date());
        int count = orderMapper.updateByPrimaryKeySelective(order);
        //插入操作记录
        OmsOrderOperateHistory history = new OmsOrderOperateHistory();
        history.setOrderId(moneyInfoParam.getOrderId());
        history.setCreateTime(new Date());
        history.setOperateMan("后台管理员");
        history.setOrderStatus(moneyInfoParam.getStatus());
        history.setNote("修改费用信息");
        orderOperateHistoryMapper.insert(history);
        return count;
    }

    @Override
    public int updateNote(Long id, String note, Integer status) {
        OmsOrder order = new OmsOrder();
        order.setId(id);
        order.setNote(note);
        order.setModifyTime(new Date());
        int count = orderMapper.updateByPrimaryKeySelective(order);
        OmsOrderOperateHistory history = new OmsOrderOperateHistory();
        history.setOrderId(id);
        history.setCreateTime(new Date());
        history.setOperateMan("后台管理员");
        history.setOrderStatus(status);
        history.setNote("修改备注信息："+note);
        orderOperateHistoryMapper.insert(history);
        return count;
    }

    @Override
    public List<OrderTrackingVO> orderTracking(Long id) {
        OmsOrder omsOrder = orderMapper.selectByPrimaryKey(id);
        List<OrderTrackingVO> ots=new ArrayList<>();
        SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        ots.add(new OrderTrackingVO("订单已提交，等待付款",sdf.format(omsOrder.getCreateTime())));
        if (omsOrder.getPaymentTime()!=null){
            ots.add(new OrderTrackingVO("订单付款成功,等待发货",sdf.format(omsOrder.getPaymentTime())));
        }
        if (omsOrder.getDeliveryTime()!=null){
            QueryTrackReq queryTrackReq = new QueryTrackReq();
            QueryTrackParam queryTrackParam = new QueryTrackParam();
            queryTrackParam.setCom(new FastCoding().getMap().get(omsOrder.getDeliveryCompany()));
            queryTrackParam.setNum(omsOrder.getDeliverySn());
            queryTrackReq.setCustomer("26B7D406A83CF9067BD93D4BDECEA8AE");
            queryTrackReq.setParam(queryTrackParam);
            queryTrackReq.setSign(SignUtils.sign(JSONObject.fromObject(queryTrackParam).toString()+"ZpPkoKff3913"+queryTrackReq.getCustomer()));
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            CloseableHttpResponse resp = null;
            HttpResult result = new HttpResult();
            try {
                Map<String, String> params = objectToMap(queryTrackReq);
                HttpPost httpPost = new HttpPost("https://poll.kuaidi100.com/poll/query.do");
                if (params != null && params.size() > 0) {
                    List<NameValuePair> list = new ArrayList<NameValuePair>();
                    for (Map.Entry<String, String> entry : params.entrySet()) {
                        list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                    }
                    httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8"));
                }
                resp = httpClient.execute(httpPost);
                String body = EntityUtils.toString(resp.getEntity(), "UTF-8");
                Map<String,Object> res = JSON.parseObject(body,Map.class);
                List<LogisticsVO> item = JSON.parseArray(res.get("data").toString(),LogisticsVO.class);
                Collections.reverse(item);
                for (LogisticsVO lgs:item){
                    ots.add(new OrderTrackingVO(lgs.getContext(),lgs.getTime()));
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ots;
    }

    @Override
    public void orderCancel(Long id) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        OmsOrder omsOrder = orderMapper.selectByPrimaryKey(id);
        omsOrder.setStatus(4);
        omsOrder.setModifyTime(new Date());
        Map<String,Object> map = new HashMap<>();
        map.put("account",env.getProperty("pay.account"));
        map.put("upOrderId",omsOrder.getTongGuanSn());
        map.put("refundMoney",omsOrder.getPayAmount().subtract(omsOrder.getDiscountAmount()).toString());
        String s = "account="+map.get("account")+"&refundMoney="+map.get("refundMoney")+"&upOrderId="+map.get("upOrderId")+"&key="+env.getProperty("pay.sign");
        map.put("sign", KeyedDigestMD5.getKeyedDigest("",s).toUpperCase());
        String data = JSONObject.fromObject(map).toString();
        String res = HttpKit.post(env.getProperty("pay.refundUrl"),data,headers);
        Map<String, Object> resMap = JSON.parseObject(res,Map.class);
        if ((int)resMap.get("status")==100 && resMap.get("state").toString().equals("5")){
            orderMapper.updateByPrimaryKeySelective(omsOrder);
            OmsOrderOperateHistory history = new OmsOrderOperateHistory();
            history.setOrderId(omsOrder.getId());
            history.setCreateTime(new Date());
            history.setOperateMan("后台管理员");
            history.setOrderStatus(omsOrder.getStatus());
            history.setNote("取消订单");
            orderOperateHistoryMapper.insert(history);
        }else {
            Asserts.fail("退款失败");
        }
    }

    public static Map<String, String> objectToMap(Object obj) throws IllegalAccessException {
        if (obj == null) {
            return null;
        }
        Map<String, String> map = new HashMap<String,String>();
        Class<?> clazz = obj.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            String fieldValue = "";
            if (field.getType()== String.class || field.getType() == Integer.class || field.getType() == int.class){
                fieldValue = field.get(obj)==null?"": field.get(obj).toString();
            }else {
                fieldValue = JSONObject.fromObject(field.get(obj)).toString();
            }
            map.put(fieldName, fieldValue);
        }
        return map;
    }
}
